home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / editors / emacs / xemacs / xemacs-1.006 / xemacs-1 / lib / xemacs-19.13 / lisp / prim / glyphs.el < prev    next >
Encoding:
Text File  |  1995-08-15  |  20.0 KB  |  454 lines

  1. ;;; glyphs.el --- Lisp interface to C glyphs
  2. ;; Keywords: glyphs internal
  3.  
  4. ;; Copyright (C) 1994 Board of Trustees, University of Illinois
  5. ;; Copyright (C) 1995 Ben Wing
  6.  
  7. ;; Author: Chuck Thompson <cthomp@cs.uiuc.edu>,
  8. ;;         Ben Wing <wing@netcom.com>
  9.  
  10. ;; This file is part of XEmacs.
  11.  
  12. ;; XEmacs is free software; you can redistribute it and/or modify it
  13. ;; under the terms of the GNU General Public License as published by
  14. ;; the Free Software Foundation; either version 2, or (at your option)
  15. ;; any later version.
  16.  
  17. ;; XEmacs is distributed in the hope that it will be useful, but
  18. ;; WITHOUT ANY WARRANTY; without even the implied warranty of
  19. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  20. ;; General Public License for more details.
  21.  
  22. ;; You should have received a copy of the GNU General Public License
  23. ;; along with XEmacs; see the file COPYING.  If not, write to the Free
  24. ;; Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  25.  
  26. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; font specifiers
  27.  
  28. (defun make-image-specifier (spec-list)
  29.   "Create a new `image' specifier object with the given specification list.
  30. SPEC-LIST can be a list of specifications (each of which is a cons of a
  31. locale and a list of instantiators), a single instantiator, or a list
  32. of instantiators.  See `make-specifier' for more information about
  33. specifiers."
  34.   (make-specifier-and-init 'image spec-list))
  35.  
  36. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; glyphs
  37.  
  38. (defconst built-in-glyph-specifiers
  39.   '(image contrib-p baseline)
  40.   "A list of the built-in face properties that are specifiers.")
  41.  
  42. (defun glyph-property (glyph property &optional locale)
  43.   "Return GLYPH's value of the given PROPERTY.
  44.  
  45. If LOCALE is omitted, the GLYPH's actual value for PROPERTY will be
  46.   returned.  For built-in properties, this will be a specifier object
  47.   of a type appropriate to the property (e.g. a font or color
  48.   specifier).  For other properties, this could be anything.
  49.  
  50. If LOCALE is supplied, then instead of returning the actual value,
  51.   the specification(s) for the given locale or locale type will
  52.   be returned.  This will only work if the actual value of
  53.   PROPERTY is a specifier (this will always be the case for built-in
  54.   properties, but not or not may apply to user-defined properties).
  55.   If the actual value of PROPERTY is not a specifier, this value
  56.   will simply be returned regardless of LOCALE.
  57.  
  58. The return value will be a list of instantiators (e.g. strings
  59.   specifying a font or color name), or a list of specifications, each
  60.   of which is a cons of a locale and a list of instantiators.
  61.   Specifically, if LOCALE is a particular locale (a buffer, window,
  62.   frame, device, or 'global), a list of instantiators for that locale
  63.   will be returned.  Otherwise, if LOCALE is a locale type (one of
  64.   the symbols 'buffer, 'window, 'frame, 'device, 'device-class, or
  65.   'device-type), the specifications for all locales of that type will
  66.   be returned.  Finally, if LOCALE is 'all, the specifications for all
  67.   locales of all types will be returned.
  68.  
  69. The specifications in a specifier determine what the value of
  70.   PROPERTY will be in a particular \"domain\" or set of circumstances,
  71.   which is typically a particular Emacs window along with the buffer
  72.   it contains and the frame and device it lies within.  The value
  73.   is derived from the instantiator associated with the most specific
  74.   locale (in the order buffer, window, frame, device, and 'global)
  75.   that matches the domain in question.  In other words, given a domain
  76.   (i.e. an Emacs window, usually), the specifier for PROPERTY will first
  77.   be searched for a specification whose locale is the buffer contained
  78.   within that window; then for a specification whose locale is the window
  79.   itself; then for a specification whose locale is the frame that the
  80.   window is contained within; etc.  The first instantiator that is
  81.   valid for the domain (usually this means that the instantiator is
  82.   recognized by the device [i.e. the X server or TTY device] that the
  83.   domain is on.  The function `glyph-property-instance' actually does
  84.   all this, and is used to determine how to display the glyph.
  85.  
  86. See `set-glyph-property' for the built-in property-names."
  87.  
  88.   (let ((value (get glyph property)))
  89.     (if (and locale
  90.          (or (memq property built-in-glyph-specifiers)
  91.          (specifierp value)))
  92.     (setq value (specifier-specs value locale)))
  93.     value))
  94.  
  95. (defun convert-glyph-property-into-specifier (glyph property)
  96.   "Convert PROPERTY on GLYPH into a specifier, if it's not already."
  97.   (setq glyph (get-glyph glyph))
  98.   (let ((specifier (get glyph property)))
  99.     ;; if a user-property does not have a specifier but a
  100.     ;; locale was specified, put a specifier there.  
  101.     ;; If there was already a value there, convert it to a
  102.     ;; specifier with the value as its 'global instantiator.
  103.     (if (not (specifierp specifier))
  104.     (let ((new-specifier (make-specifier 'generic)))
  105.       (if (or (not (null specifier))
  106.           ;; make sure the nil returned from `get' wasn't
  107.           ;; actually the value of the property
  108.           (null (get glyph property t)))
  109.           (add-spec-to-specifier new-specifier specifier))
  110.       (setq specifier new-specifier)
  111.       (put glyph property specifier)))))
  112.  
  113. (defun glyph-property-instance (glyph property
  114.                       &optional domain default no-fallback)
  115.   "Return the instance of GLYPH's PROPERTY in the specified DOMAIN.
  116.  
  117. Under most circumstances, DOMAIN will be a particular window,
  118.   and the returned instance describes how the specified property
  119.   actually is displayed for that window and the particular buffer
  120.   in it.  Note that this may not be the same as how the property
  121.   appears when the buffer is displayed in a different window or
  122.   frame, or how the property appears in the same window if you
  123.   switch to another buffer in that window; and in those cases,
  124.   the returned instance would be different.
  125.  
  126. The returned instance will typically be a color-instance,
  127.   font-instance, or pixmap-instance object, and you can query
  128.   it using the appropriate object-specific functions.  For example,
  129.   you could use `color-instance-rgb-components' to find out the
  130.   RGB (red, green, and blue) components of how the 'background
  131.   property of the 'highlight glyph is displayed in a particular
  132.   window.  The results might be different from the results
  133.   you would get for another window (perhaps the user
  134.   specified a different color for the frame that window is on;
  135.   or perhaps the same color was specified but the window is
  136.   on a different X server, and that X server has different RGB
  137.   values for the color from this one).
  138.  
  139. DOMAIN defaults to the selected window if omitted.
  140.  
  141. DOMAIN can be a frame or device, instead of a window.  The value
  142.   returned for a such a domain is used in special circumstances
  143.   when a more specific domain does not apply; for example, a frame
  144.   value might be used for coloring a toolbar, which is conceptually
  145.   attached to a frame rather than a particular window.  The value
  146.   is also useful in determining what the value would be for a
  147.   particular window within the frame or device, if it is not
  148.   overridden by a more specific specification.
  149.  
  150. If PROPERTY does not name a built-in property, its value will
  151.   simply be returned unless it is a specifier object, in which case
  152.   it will be instanced using `specifier-instance'.
  153.  
  154. Optional arguments DEFAULT and NO-FALLBACK are the same as in
  155.   `specifier-instance'."
  156.  
  157.   (let ((value (get glyph property)))
  158.     (if (specifierp value)
  159.     (setq value (specifier-instance value domain default no-fallback)))
  160.     value))
  161.  
  162. (defun set-glyph-property (glyph property value &optional locale tag-set how-to-add)
  163.   "Change a property of a GLYPH.
  164.  
  165. NOTE: If you want to remove a property from a glyph, use `remove-glyph-property'
  166.   rather than attempting to set a value of nil for the property.
  167.  
  168. For built-in properties, the actual value of the property is a
  169.   specifier and you cannot change this; but you can change the
  170.   specifications within the specifier, and that is what this function
  171.   will do.  For user-defined properties, you can use this function
  172.   to either change the actual value of the property or, if this value
  173.   is a specifier, change the specifications within it.
  174.  
  175. If PROPERTY is a built-in property, the specifications to be added to
  176.   this property can be supplied in many different ways:
  177.  
  178.   -- If VALUE is a simple instantiator (e.g. a string naming a font or
  179.      color) or a list of instantiators, then the instantiator(s) will
  180.      be added as a specification of the property for the given LOCALE
  181.      (which defaults to 'global if omitted).
  182.   -- If VALUE is a list of specifications (each of which is a cons of
  183.      a locale and a list of instantiators), then LOCALE must be nil
  184.      (it does not make sense to explicitly specify a locale in this
  185.      case), and specifications will be added as given.
  186.   -- If VALUE is a specifier (as would be returned by `glyph-property'
  187.      if no LOCALE argument is given), then some or all of the
  188.      specifications in the specifier will be added to the property.
  189.      In this case, the function is really equivalent to
  190.      `copy-specifier' and LOCALE has the same semantics (if it is
  191.      a particular locale, the specification for the locale will be
  192.      copied; if a locale type, specifications for all locales of
  193.      that type will be copied; if nil or 'all, then all
  194.      specifications will be copied).
  195.  
  196. HOW-TO-ADD should be either nil or one of the symbols 'prepend,
  197.   'append, 'remove-tag-set-prepend, 'remove-tag-set-append, 'remove-locale,
  198.   'remove-locale-type, or 'remove-all.  See `copy-specifier' and
  199.   `add-spec-to-specifier' for a description of what each of
  200.   these means.  Most of the time, you do not need to worry about
  201.   this argument; the default behavior usually is fine.
  202.  
  203. In general, it is OK to pass an instance object (e.g. as returned
  204.   by `glyph-property-instance') as an instantiator in place of
  205.   an actual instantiator.  In such a case, the instantiator used
  206.   to create that instance object will be used (for example, if
  207.   you set a font-instance object as the value of the 'font
  208.   property, then the font name used to create that object will
  209.   be used instead).  If some cases, however, doing this
  210.   conversion does not make sense, and this will be noted in
  211.   the documentation for particular types of instance objects.
  212.  
  213. If PROPERTY is not a built-in property, then this function will
  214.   simply set its value if LOCALE is nil.  However, if LOCALE is
  215.   given, then this function will attempt to add VALUE as the
  216.   instantiator for the given LOCALE, using `add-spec-to-specifier'.
  217.   If the value of the property is not a specifier, it will
  218.   automatically be converted into a 'generic specifier.
  219.  
  220.  
  221. The following symbols have predefined meanings:
  222.  
  223.  image            The image used to display the glyph.
  224.  
  225.  baseline        Percent above baseline that glyph is to be
  226.             displayed.
  227.  
  228.  contrib-p        Whether the glyph contributes to the
  229.             height of the line it's on.
  230.  
  231.  face            Face of this glyph (*not* a specifier)."
  232.  
  233.   (if (memq property built-in-glyph-specifiers)
  234.       ;; This section adds built-in properties.
  235.       (let ((specifier (get glyph property))
  236.         (nval value))
  237.     (cond ((specifierp value)
  238.            (copy-specifier value specifier locale tag-set nil how-to-add))
  239.           (t
  240.            (if tag-set
  241.            (progn
  242.              (or (not (consp nval))
  243.              (error
  244.               "Must specify single instantiator if TAG-SET is given"))
  245.              (setq nval
  246.                (cons tag-set nval))))
  247.            (if locale
  248.            (setq nval (cons locale nval)))
  249.            (set-specifier specifier nval how-to-add))))
  250.  
  251.     ;; This section adds user defined properties.
  252.     (if (not locale)
  253.     (put glyph property value)
  254.       (convert-glyph-property-into-specifier glyph property)
  255.       (add-spec-to-specifier (get glyph property) value locale tag-set how-to-add)))
  256.   value)
  257.  
  258. (defun remove-glyph-property (glyph property &optional locale tag-set exact-p)
  259.   "Remove a property from a glyph.
  260. For built-in properties, this is analogous to `remove-specifier'.
  261. See `remove-specifier' for the meaning of the LOCALE, TAG-SET, and EXACT-P arguments."
  262.   (or locale (setq locale 'all))
  263.   (if (memq property built-in-glyph-specifiers)
  264.       (remove-specifier (glyph-property glyph property) locale tag-set exact-p)
  265.     (if (eq locale 'all)
  266.     (remprop (get-glyph glyph) property)
  267.       (convert-glyph-property-into-specifier glyph property)
  268.       (remove-specifier (glyph-property glyph property) locale tag-set exact-p))))
  269.  
  270. (defun glyph-face (glyph)
  271.   "Return the face of GLYPH."
  272.   (glyph-property glyph 'face))
  273.  
  274. (defun set-glyph-face (glyph face)
  275.   "Change the face of GLYPH to FACE."
  276. ;  (interactive (glyph-interactive "face"))
  277.   (set-glyph-property glyph 'face face))
  278.  
  279. (defun glyph-image (glyph &optional locale)
  280.   "Return the image of the given glyph, or nil if it is unspecified.
  281.  
  282. LOCALE may be a locale (the instantiators for that particular locale
  283.   will be returned), a locale type (the specifications for all locales
  284.   of that type will be returned), 'all (all specifications will be
  285.   returned), or nil (the actual specifier object will be returned).
  286.  
  287. See `glyph-property' for more information."
  288.   (glyph-property glyph 'image locale))
  289.  
  290. (defun glyph-image-instance (glyph &optional domain default no-fallback)
  291.   "Return the instance of the given glyph's image in the given domain.
  292.  
  293. Normally DOMAIN will be a window or nil (meaning the selected window),
  294.   and an instance object describing how the image appears in that
  295.   particular window and buffer will be returned.
  296.  
  297. See `glyph-property-instance' for more information."
  298.   (glyph-property-instance glyph 'image domain default no-fallback))
  299.  
  300. (defun set-glyph-image (glyph spec &optional locale tag-set how-to-add)
  301.   "Change the image of the given glyph.
  302.  
  303. SPEC should be an instantiator (a string or vector; see
  304.   `image-specifier-p' for a description of possible values here),
  305.   a list of (possibly tagged) instantiators, an alist of specifications
  306.   (each mapping a locale to an instantiator list), or an image specifier
  307.   object.
  308.  
  309. If SPEC is an alist, LOCALE must be omitted.  If SPEC is a
  310.   specifier object, LOCALE can be a locale, a locale type, 'all,
  311.   or nil; see `copy-specifier' for its semantics.  Otherwise LOCALE
  312.   specifies the locale under which the specified instantiator(s)
  313.   will be added, and defaults to 'global.
  314.  
  315. See `set-glyph-property' for more information."
  316.   ; (interactive (glyph-interactive "image"))
  317.   (set-glyph-property glyph 'image spec locale tag-set how-to-add))
  318.  
  319. (defun glyph-contrib-p (glyph &optional locale)
  320.   "Return whether GLYPH contributes to its line height.
  321.  
  322. LOCALE may be a locale (the instantiators for that particular locale
  323.   will be returned), a locale type (the specifications for all locales
  324.   of that type will be returned), 'all (all specifications will be
  325.   returned), or nil (the actual specifier object will be returned).
  326.  
  327. See `glyph-property' for more information."
  328.   (glyph-property glyph 'contrib-p locale))
  329.  
  330. (defun glyph-contrib-p-instance (glyph &optional domain default no-fallback)
  331.   "Return the instance of the GLYPH's 'contrib-p property in the given domain.
  332.  
  333. Normally DOMAIN will be a window or nil (meaning the selected window),
  334.   and an instance object describing what the 'contrib-p property is in
  335.   that particular window and buffer will be returned.
  336.  
  337. See `glyph-property-instance' for more information."
  338.   (glyph-property-instance glyph 'contrib-p domain default no-fallback))
  339.  
  340. (defun set-glyph-contrib-p (glyph spec &optional locale tag-set how-to-add)
  341.   "Change the contrib-p of the given glyph.
  342.  
  343. SPEC should be an instantiator (t or nil), a list of (possibly
  344.   tagged) instantiators, an alist of specifications (each mapping a
  345.   locale to an instantiator list), or a boolean specifier object.
  346.  
  347. If SPEC is an alist, LOCALE must be omitted.  If SPEC is a
  348.   specifier object, LOCALE can be a locale, a locale type, 'all,
  349.   or nil; see `copy-specifier' for its semantics.  Otherwise LOCALE
  350.   specifies the locale under which the specified instantiator(s)
  351.   will be added, and defaults to 'global.
  352.  
  353. See `set-glyph-property' for more information."
  354.   ; (interactive (glyph-interactive "contrib-p"))
  355.   (set-glyph-property glyph 'contrib-p spec locale tag-set how-to-add))
  356.  
  357. (defun glyph-baseline (glyph &optional locale)
  358.   "Return the baseline of the given glyph, or nil if it is unspecified.
  359.  
  360. LOCALE may be a locale (the instantiators for that particular locale
  361.   will be returned), a locale type (the specifications for all locales
  362.   of that type will be returned), 'all (all specifications will be
  363.   returned), or nil (the actual specifier object will be returned).
  364.  
  365. See `glyph-property' for more information."
  366.   (glyph-property glyph 'baseline locale))
  367.  
  368. (defun glyph-baseline-instance (glyph &optional domain default no-fallback)
  369.   "Return the instance of the given glyph's baseline in the given domain.
  370.  
  371. Normally DOMAIN will be a window or nil (meaning the selected window),
  372.   and an integer or nil (specifying the baseline in that particular
  373.   window and buffer) will be returned.
  374.  
  375. See `glyph-property-instance' for more information."
  376.   (glyph-property-instance glyph 'baseline domain default no-fallback))
  377.  
  378. (defun set-glyph-baseline (glyph spec &optional locale tag-set how-to-add)
  379.   "Change the baseline of the given glyph.
  380.  
  381. SPEC should be an instantiator (an integer [a percentage above the
  382.   baseline of the line the glyph is on] or nil), a list of (possibly
  383.   tagged) instantiators, an alist of specifications (each mapping a
  384.   locale to an instantiator list), or a generic specifier object.
  385.  
  386. If SPEC is an alist, LOCALE must be omitted.  If SPEC is a
  387.   specifier object, LOCALE can be a locale, a locale type, 'all,
  388.   or nil; see `copy-specifier' for its semantics.  Otherwise LOCALE
  389.   specifies the locale under which the specified instantiator(s)
  390.   will be added, and defaults to 'global.
  391.  
  392. See `set-glyph-property' for more information."
  393.   ; (interactive (glyph-interactive "baseline"))
  394.   (set-glyph-property glyph 'baseline spec locale tag-set how-to-add))
  395.  
  396. (defun make-glyph (&optional spec-list type)
  397.   "Create a new `glyph' object with the given specification list.
  398. SPEC-LIST can be a list of specifications (each of which is a cons of a
  399. locale and a list of inst-pairs, each of which is a cons of a tag-set and
  400. an instantiator), a single instantiator, a list of instantiators, or
  401. almost any other reasonable form (specifically anything accepted by
  402. `canonicalize-spec-list').  SPEC-LIST is used to initialize the
  403. glyph's 'image property, which is a specifier.  See `make-specifier'
  404. for more information about specifiers."
  405.   (let ((glyph (make-glyph-internal type)))
  406.     (set-glyph-image glyph spec-list)
  407.     glyph))
  408.  
  409. (defun init-glyphs ()
  410.   ;; initialize default image types
  411.   (if (featurep 'x)
  412.     (set-device-type-image-conversion-list 'x
  413.      `(,@(if (featurep 'xpm) '(("\.xpm$" [xpm :file nil] 2)))
  414.        ,@(if (featurep 'xpm) '(("^/\\* XPM \\*/" [xpm :data nil] 2)))
  415.        ,@(if (featurep 'xface) '(("^X-Face:" [xface :data nil] 2)))
  416.        ("" [autodetect :data nil] 2))))
  417.   ;; #### this should really be formatted-string, not string but we
  418.   ;; don't have it implemented yet
  419.   ;;
  420.   ;; #define could also mean a bitmap as well as a version 1 XPM.  Who
  421.   ;; cares.  We don't want the file contents getting converted to a
  422.   ;; string in either case which is why the entry is there.
  423.   (set-device-type-image-conversion-list 'tty
  424.    '(("^#define" [string :data "[xpm]"])
  425.      ("^X-Face:" [string :data "[xface]"])
  426.      ("^/\\* XPM \\*/" [string :data "[xpm]"])
  427.      ("" [string :data nil] 2)))
  428.  
  429.   ;; finish initializing truncation glyph -- created internally
  430.   ;; because it has a built-in bitmap
  431.   (set-glyph-image truncation-glyph "$" 'global 'tty)
  432.  
  433.   ;; finish initializing truncation glyph -- created internally
  434.   ;; because it has a built-in bitmap
  435.   (set-glyph-image continuation-glyph "\\" 'global 'tty)
  436.  
  437.   (setq octal-escape-glyph (make-glyph "\\"))
  438.   (setq control-arrow-glyph (make-glyph "^"))
  439.   (setq invisible-text-glyph (make-glyph " ..."))
  440.   (setq hscroll-glyph (make-glyph "$"))
  441.  
  442.   ;; finish initializing xemacs logo -- created internally because it
  443.   ;; has a built-in bitmap
  444.   (if (featurep 'xpm)
  445.       (set-glyph-image xemacs-logo
  446.                (format "%s%s" data-directory "xemacs.xpm")
  447.                'global 'x))
  448.   (set-glyph-image xemacs-logo
  449.            "XEmacs <insert spiffy graphic logo here>"
  450.            'global 'tty)
  451. )
  452.  
  453. ;;; glyphs.el ends here.
  454.